package top.lucky.elasticsearch.client;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.xcontent.XContentType;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import top.lucky.elasticsearch.entity.User;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Jane
 * @date 2022/10/29, 22:23
 */
@Slf4j
public class CreateConnect {
	
	private RestHighLevelClient highLevelClient;
	
	@Before
	public void createConn() {
		highLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1", 9200, "http")
		));
	}
	
	@Test
	public  void testCreateIndex() throws Exception{
		//创建createIndexRequest对象,指定index索引库名称
		CreateIndexRequest request = new CreateIndexRequest("user");
		//指定setting配置
		Map<String, Object> settings = new HashMap<String, Object>();
		settings.put("number_of_shards", 3);
		settings.put("number_of_replicas", 1);
		request.settings(settings);
		//指定mapping配置
		request.mapping(
			"{\n" +
				"    \"properties\": {\n" +
				"      \"id\": {\n" +
				"        \"type\": \"long\"\n" +
				"      },\n" +
				"      \"name\":{\n" +
				"        \"type\": \"keyword\"\n" +
				"      },\n" +
				"      \"age\":{\n" +
				"        \"type\": \"integer\"\n" +
				"      },\n" +
				"      \"gender\":{\n" +
				"        \"type\": \"keyword\"\n" +
				"      },\n" +
				"      \"note\":{\n" +
				"        \"type\": \"text\",\n" +
				"        \"analyzer\": \"ik_max_word\"\n" +
				"      }\n" +
				"    }\n" +
				"  }",
			//指定映射的内容的类型为json
			XContentType.JSON);
		//发送请求,获取响应
		CreateIndexResponse createIndexResponse = highLevelClient.indices().create(request, RequestOptions.DEFAULT);
		System.out.println("createIndexResponse = " + JSON.toJSONString(createIndexResponse));
	}
	
	@Test
	public void testAddDoc() {
		User user = new User();
		user.setId(10000L);
		user.setName("张三");
		user.setAge(25);
		user.setGender("男");
		user.setNote("上海市");
		IndexRequest indexRequest = new IndexRequest("user");
		indexRequest.id(user.getId().toString());
		indexRequest.source(JSON.toJSONString(user), XContentType.JSON);
		try {
			IndexResponse index = highLevelClient.index(indexRequest, RequestOptions.DEFAULT);
			System.out.println(index.getResult());
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	
	@Test
	public void getDoc() throws Exception{
		GetRequest indexRequest = new GetRequest("user");
		indexRequest.id("10000");
		GetResponse documentFields = highLevelClient.get(indexRequest, RequestOptions.DEFAULT);
		String sourceAsString = documentFields.getSourceAsString();
		User user = JSON.parseObject(sourceAsString, User.class);
		System.out.println(user);
	}
	
	@Test
	public void getDeleteDoc() throws Exception{
		DeleteRequest deleteRequest = new DeleteRequest("user", "10000");
		DeleteResponse delete = highLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
		System.out.println(delete);
	}
	
	@Test
	public void getAll() throws Exception {
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		searchSourceBuilder.query(QueryBuilders.matchAllQuery());
		SearchRequest searchRequest = new SearchRequest("user");
		
		searchRequest.source(searchSourceBuilder);
		SearchResponse search = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
		SearchHits hits = search.getHits();
		SearchHit[] searchHits = hits.getHits();
		for (SearchHit searchHit : searchHits) {
			System.out.println("得分:"+searchHit.getScore());
			User user = JSON.parseObject(searchHit.getSourceAsString(), User.class);
			System.out.println(user);
		}
	}
	
	@Test
	public void testTermQuery() throws Exception{
		
		printResultByQuery(QueryBuilders.termQuery("note","小明"));
	}
	
	@After
	public void  destroy() {
		if (highLevelClient != null) {
			try {
				highLevelClient.close();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
	}
	
	/**
	 * 抽取通用构建查询条件执行查询方法
	 * @throws Exception
	 */
	public void printResultByQuery(QueryBuilder queryBuilder) throws Exception{
		//1. 创建SearchSourceBuilder对象
		SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
		//   ************ 构建查询条件************
		sourceBuilder.query(queryBuilder);
		
		//2. 创建SearchRequest对象，并制定索引库名称
		SearchRequest request = new SearchRequest("user");
		//3. 添加SearchSourceBuilder对象到SearchRequest对象source中
		request.source(sourceBuilder);
		//4. 发起请求，得到结果
		SearchResponse response = highLevelClient.search(request, RequestOptions.DEFAULT);
		//5. 解析结果SearchResponse
		SearchHits searchHits = response.getHits();
		//   1. 获取总条数
		System.out.println("总记录数：" + searchHits.getTotalHits().value);
		//   2. 获取SearchHits数组，并遍历
		for (SearchHit searchHit : searchHits) {
			//      * 获取其中的`_source`，是JSON数据
			String userJson = searchHit.getSourceAsString();
			//      * 把`_source`反序列化为User对象
			User user = JSON.parseObject(userJson, User.class);
			System.out.println(user);
		}
	}
}
